#include <stdio.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/select.h>
#include <errno.h>
#include <string.h>

#define BLKSIZE 1024

int readwrite(int fromfd, int tofd)
{
	char buf[BLKSIZE];
	memset(buf, 0, BLKSIZE);
	int ret = 0;
	if ((ret = read(fromfd, buf, BLKSIZE)) <= 0) {
		printf("%s: read size : %d\n", __func__, ret);
		return ret;
	}
	ret = write(tofd, buf, BLKSIZE);
	printf("%s: write size : %d\n", __func__, ret);
	return ret;
}

int copy2files(int fromfd1, int tofd1, int fromfd2, int tofd2)
{
	if (fromfd1 < 0 || fromfd2 < 0 || tofd1 < 0 || tofd2 < 0 || fromfd1 > 
			FD_SETSIZE || fromfd2 > FD_SETSIZE || tofd1 > FD_SETSIZE || 
			tofd2 > FD_SETSIZE) {
		fprintf(stderr, "%s: Param error\n", __func__);
		return -1;
	}

	int maxfd;
	int num;
	int bytesread1, bytesread2;
	int totalbytes = 0;
	fd_set readset;
	
	maxfd = fromfd1 > fromfd2 ? fromfd1 : fromfd2;
	for (; ; ) {
		FD_ZERO(&readset);
		FD_SET(fromfd1, &readset);
		FD_SET(fromfd2, &readset);
		if ((num = select(maxfd + 1, &readset, NULL, NULL, NULL)) == -1 && (errno 
					== EINTR)) {
			continue;
		}
		if (num == -1) {
			return totalbytes;
		}
		if (FD_ISSET(fromfd1, &readset)) {
			while ((bytesread1 = readwrite(fromfd1, tofd1)) == -1 && errno == EINTR);
			printf("file1 bytesread: %d\n", bytesread1);
			if (bytesread1 <= 0 && bytesread2 <= 0)
				break;
			totalbytes += bytesread1;
			printf("total bytes:%d\n", totalbytes);
		}
		if (FD_ISSET(fromfd2, &readset)) {
			while ((bytesread2 = readwrite(fromfd2, tofd2)) == -1 && errno == EINTR);
			printf("file2 bytesread: %d\n", bytesread2);
			if (bytesread1 <= 0 && bytesread2 <= 0)
				break;
			totalbytes += bytesread2;
			printf("total bytes:%d\n", totalbytes);
		}
	}
	return totalbytes;
}

int main(int argc, char **argv)
{
	int retval = 0;
	if (argc != 3) {
		fprintf(stderr, "arg error\n");
		return -1;
	}

	int ffd1, ffd2, tfd1, tfd2;

	if ((ffd1 = open(argv[1], O_RDONLY)) <= 0) {
		fprintf(stderr, "open file 1 error\n");
		return -1;
	}
	if ((ffd2 = open(argv[2], O_RDONLY)) <= 0) {
		fprintf(stderr, "open file 1 error\n");
		return -1;
	}
	if ((tfd1 = open("./file1", O_RDWR | O_CREAT | O_EXCL, S_IRWXU)) <= 0) {
		fprintf(stderr, "open tofile 1 error\n");
		return -1;
	}
	if ((tfd2 = open("./file2", O_RDWR | O_CREAT | O_EXCL, S_IRWXU)) <= 0) {
		fprintf(stderr, "open tofile 2 error\n");
		return -1;
	}
	retval = copy2files(ffd1, tfd1, ffd2, tfd2);
	if (retval < 0) {
		fprintf(stderr, "copy file error\n");
		return -1;
	}
	printf("%d bytes have been copied\n", retval);
	return 0;
}
